/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.smart.service.infohotel;

import com.smart.builder.entity.BuilderEntityHotel;
import com.smart.builder.entity.BuilderEntityRoomModel;
import com.smart.builder.xml.BuilderInfoHotelResponseType;
import com.smart.hotelsmart.InfoHotelRequestType;
import com.smart.hotelsmart.InfoHotelResponseType;
import com.smart.persistence.entity.Hotel;
import com.smart.persistence.entity.Image;
import com.smart.persistence.entity.Room;
import com.smart.persistence.entity.RoomModel;
import com.smart.persistence.service.SmartBasicCrudDAO;
import com.smart.service.infohotel.InfoWebHotelService.InfoHotel;
import com.smart.service.util.Logging;
import com.smart.service.util.UtilDate;

import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

/**
 * 
 * @author arthur
 */
public class InfoHotelService {
	/** A Constant LOGGER. */
	private static final Logging LOGGER = Logging
			.getLogger(InfoHotelService.class.getName());
	private InfoWebHotelService service = new InfoWebHotelService();

	/**
	 * generates a response
	 * two ways: 
	 * 1 - Database (data are stored) or 
	 * 2 - site (first time)
	 * 
	 * @param body
	 * @return
	 */
	public InfoHotelResponseType getInfoHotel(InfoHotelRequestType body) {
		LOGGER.debug("getInfoHotel " + body);
		assert body != null;
		
		assert body.getCodeHotel() != 0;
		Hotel entity = new BuilderEntityHotel(body.getCodeHotel(), SmartBasicCrudDAO.getInstance().getEntityManagerDAO()).getHotel();
		// Are data stored ?
		if (entity.getLatitude() == null) {
			// generates response from the web site
			assert body.getLinkSelection() != null;
			//response = generateInfoHotelResponseFromSite(body.getLinkSelection());
			InfoHotel info = service.getInfoHotelFromSite(body.getLinkSelection());
			entity = generateHotel(info, body.getCodeHotel());
		}
		assert entity.getLastUpdate() != null;
		Date departureDate = getDepartureDate(body);
		Date arrivalDate = getArrivalDate(body);
		BuilderInfoHotelResponseType builder = new BuilderInfoHotelResponseType();
		InfoHotelResponseType response = builder.generateInfoHotelResponseFromEntity(entity,arrivalDate,departureDate);
		return response;
	}

	private Date getDepartureDate(InfoHotelRequestType body) {
		Date departureDate = UtilDate.getDate(body.getDepartureDate());
		if(departureDate == null){
			departureDate = new Date(System.currentTimeMillis()+ 3 * 24 * 60 * 60 * 1000);	
		}
		return departureDate;
	}

	private Date getArrivalDate(InfoHotelRequestType body) {
		Date arrivalDate = UtilDate.getDate(body.getArrivalDate());
		if(arrivalDate == null){
			arrivalDate = new Date(System.currentTimeMillis()+ 1 * 24 * 60 * 60 * 1000);
		}
		return arrivalDate;
	}

	

	private int getCodeRoom(Map<String, String> map) {
		return new Integer(map.get(InfoWebHotelService._roomTypeCode));
	}

	
	private Hotel generateHotel(InfoHotel info, int codHotel) {
		LOGGER.debug("generateHotel");
		
		EntityManager em = SmartBasicCrudDAO.getInstance()
				.getEntityManagerDAO();
		BuilderEntityHotel builder = new BuilderEntityHotel(codHotel, em);
		EntityTransaction et = em.getTransaction();
		Hotel hotel = null;
		try {
			et.begin();
			hotel = builder.setMap(info.getMapHotel()).save(em).getHotel();
			List<String> images = info.getListImages();
			if(images != null){
				for (String string : images) {
					em.persist(new Image(string, hotel));
				}
			}
			for (int i = 0; i < info.getListMapRoom().size(); i++) {
				Map<String, String> map = info.getListMapRoom().get(i);
				RoomModel roomModel = new BuilderEntityRoomModel(getCodeRoom(map), em).setHotel(hotel).setMap(map).save(em).getRoomT();
				assert roomModel != null : "roomModel == null";
				// for each room type creates 20 room
				for (int j = 0; j < 20; j++) {
					Room room = new Room();
					room.setNumber(j);
					room.setRoomType(roomModel);
					em.persist(room);
				}
			}
			em.flush();
			et.commit();
		} catch (Exception e) {
			e.printStackTrace();
			et.rollback();

		} finally {
			em.clear();
			hotel = builder.find(em).getHotel();
			em.close();
		}
		return hotel;
	}
	

	
}
